import 'package:flutter/material.dart';

class SlidingAWidget extends StatelessWidget {
    
    final Widget drawer;
    final MenuController menuController;
    
    const SlidingAWidget({Key key, @required this.drawer, @required this.menuController}) : super(key: key);
    
    @override
    Widget build(BuildContext context) {
        return Stack(
            children: <Widget>[
                
                GestureDetector(
                    onTap: menuController.isOpen() ? menuController.close : null,
                ),
                
                FractionalTranslation(
                    translation: Offset(1 - menuController.percentOpen, 0),
                    child: drawer
                )
            ],)
        
        ;
    }
}

class MenuController extends ChangeNotifier //继承自ChangeNotifier用于分发动画的每一帧
    {
    
    MenuState _state = MenuState.closed;
    
    AnimationController openingAnimationController;
    
    MenuController({
        @required TickerProvider vsync,
        @required Duration openDuration,
    }) :
            openingAnimationController = AnimationController(duration: openDuration, vsync: vsync) {
        openingAnimationController
            ..addListener(() {
                notifyListeners(); //动画的每一帧通知listener
            })
            ..addStatusListener((AnimationStatus status) {
                switch (status) {
                    case AnimationStatus.forward:
                        _state = MenuState.opening;
                        break;
                    case AnimationStatus.completed:
                        _state = MenuState.open;
                        break;
                    case AnimationStatus.reverse:
                        _state = MenuState.closing;
                        break;
                    case AnimationStatus.dismissed:
                        _state = MenuState.closed;
                        break;
                }
            });
    }
    
    get state => _state;
    
    get percentOpen => openingAnimationController.value;
    
    bool isOpen() {
        return _state == MenuState.open;
    }
    
    bool isOpening() {
        return _state == MenuState.opening;
    }
    
    bool isClosed() {
        return _state == MenuState.closed;
    }
    
    bool isClosing() {
        return _state == MenuState.closing;
    }
    
    void open() {
        openingAnimationController.forward();
    }
    
    void close() {
        openingAnimationController.reverse();
    }
    
    void toggle() {
        if (isClosed()) {
            open();
        } else if (isOpen()) {
            close();
        }
    }
    
}

enum MenuState {
    closed,
    opening,
    open,
    closing
}